/**
* 设备管理
*/
<template>
  <div>
    <el-page-header @back="$router.back(-1)" content="设备详情">
    </el-page-header>
    <el-divider></el-divider>
    <el-tabs v-model="activeName" @tab-click="handleClick">
      <el-tab-pane label="基本信息" name="base">
        <el-descriptions :column="2" border :labelStyle="{'font-weight':'bold'}">
          <el-descriptions-item label="设备ID">{{deviceDetail.deviceId}}</el-descriptions-item>
          <el-descriptions-item label="产品productKey">{{deviceDetail.productKey}}</el-descriptions-item>
          <el-descriptions-item label="设备deviceName">{{deviceDetail.deviceName}}</el-descriptions-item>
          <el-descriptions-item label="创建时间">{{deviceDetail.createAt|timestampToTime}}</el-descriptions-item>
          <el-descriptions-item label="设备状态">{{deviceDetail.state?(deviceDetail.state.online?'在线':'离线'):'离线'}}</el-descriptions-item>
          <el-descriptions-item label="最后上线时间">{{deviceDetail.onlineTime|timestampToTime}}</el-descriptions-item>
        </el-descriptions>
      </el-tab-pane>
      <el-tab-pane label="属性" name="property">
        <el-table
          :data="properties"
          border
          style="width: 100%">
          <el-table-column
            prop="name"
            label="属性名"
            width="180">
            <template slot-scope="scope">
              {{scope.row.name}}({{scope.row.identifier}})
            </template>
          </el-table-column>
          <el-table-column
            prop="value"
            label="属性值"
            width="180">
          </el-table-column>
          <el-table-column
            label="可读写">
            <template slot-scope="scope">
              <el-tag v-if="!scope.row.write" type="info" size="mini" effect="plain">只读</el-tag>
              <el-button @click="showWriteProperty(scope.row)" v-if="scope.row.write" size="mini" type="success"
                plain>可写</el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-tab-pane>
      <el-tab-pane label="服务" name="service">
        <el-table
          :data="services"
          border
          style="width: 100%">
          <el-table-column
            label="服务名称"
            width="180">
            <template slot-scope="scope">
              {{scope.row.name}}({{scope.row.identifier}})
            </template>
          </el-table-column>
          <el-table-column
            label="操作"
            width="100">
            <template slot-scope="scope">
              <el-button @click="showInvokeService(scope.row)" type="success" size="mini" plain>调用</el-button>
            </template>
          </el-table-column>
          <el-table-column
            label="参数">
            <template slot-scope="scope">
              {{scope.row.inputData}}
            </template>
          </el-table-column>
        </el-table>
      </el-tab-pane>
      <el-tab-pane label="事件和日志" name="event">

        <el-form :inline="true" :model="formInline" class="user-search">
          <el-form-item>
            <el-select size="small" v-model="formInline.type" placeholder="请选择日志类型">
              <el-option label="所有日志" value=""></el-option>
              <el-option label="设备事件" value="event"></el-option>
              <el-option label="属性上报" value="property"></el-option>
              <el-option label="服务调用" value="service"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="搜索：">
            <el-input size="small" v-model="formInline.identifier" placeholder="事件标识符"></el-input>
          </el-form-item>
          <el-form-item>
            <el-button size="small" type="primary" icon="el-icon-search" @click="logSearch">搜索</el-button>
          </el-form-item>
        </el-form>

        <el-table
          :data="events"
          border
          style="width: 100%">
          <el-table-column
            label="时间"
            width="180">
            <template slot-scope="scope">
              {{scope.row.createAt|timestampToTime}}
            </template>
          </el-table-column>
          <el-table-column
            prop="name"
            label="事件名称"
            width="180">
          </el-table-column>
          <el-table-column
            label="事件内容">
            <template slot-scope="scope">
              {{scope.row.request}}
            </template>
          </el-table-column>
        </el-table>
        <Pagination v-bind:child-msg="pageparm" @callFather="callFather"></Pagination>
      </el-tab-pane>
    </el-tabs>
    <el-dialog :title="title" :visible.sync="propertyWriteFormVisible" width="40%" @click="closeDialog">
      <el-form label-width="120px" :model="propertyWriteForm" ref="propertyWriteForm">
        <div style="display:none">
          <el-input size="small" v-model="propertyWriteForm.identifier" type="hidden"></el-input>
        </div>
        <el-form-item label="属性值" prop="value">
          <el-input size="small" v-model="propertyWriteForm.value" auto-complete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button size="small" @click="closeDialog">取消</el-button>
        <el-button size="small" type="primary" :loading="loading" class="title" @click="submitPropertyWriteForm('propertyWriteForm')">保存</el-button>
      </div>
    </el-dialog>

    <el-dialog :title="title" :visible.sync="serviceFormVisible" width="40%" @click="closeDialog">
      <el-form label-width="120px" :model="serviceForm" ref="serviceForm">
        <div style="display:none">
          <el-input size="small" v-model="serviceForm.identifier" type="hidden"></el-input>
          <el-input size="small" v-model="serviceForm.productKey" type="hidden"></el-input>
          <el-input size="small" v-model="serviceForm.deviceName" type="hidden"></el-input>
        </div>
        <el-form-item v-for="param in serviceForm.params" :key="param.identifier" :label="param.name+'('+param.identifier+')'"
          prop="params">
          <el-input size="small" v-model="param.value" auto-complete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button size="small" @click="closeDialog">取消</el-button>
        <el-button size="small" type="primary" :loading="loading" class="title" @click="submitServiceForm('serviceForm')">保存</el-button>
      </div>
    </el-dialog>
    <div v-if="!showConsole" class="console-bar">
      <el-row>
        <el-col :span="10">&nbsp;</el-col>
        <el-col :span="2">
          <el-button size="small" @click="openDebug" plain icon="el-icon-arrow-up">打开调试</el-button>
        </el-col>
      </el-row>
    </div>
    <div v-if="showConsole" class="console">
      <el-row>
        <el-col :span="10">&nbsp;</el-col>
        <el-col :span="4">
          <el-button size="small" @click="closeDebug" plain icon="el-icon-arrow-down">关闭调试</el-button>
          <el-button size="small" @click="clearConsole" plain circle icon="el-icon-delete"></el-button>
        </el-col>
      </el-row>
      <ol class="output">
        <li v-for="log in deviceLogs" :key="log.identifier">{{log}}</li>
      </ol>
    </div>
  </div>
</template>

<script>
  import {
    GetThingModel
  } from '../../api/productApi'
  import {
    DeviceDetail,
    PropertySet,
    DeviceEvents,
    ServiceInvoke
  } from '../../api/deviceApi'
  import {
    timestampToTime
  } from '../../utils/util'
  var mqtt = require('mqtt')
  import Pagination from '../../components/Pagination'
  export default {
    data() {
      return {
        loading: false, //是显示加载
        activeName: 'base',
        title: '预览',
        propertyWriteFormVisible: false,
        propertyWriteForm: {
          identifier: '',
          productKey: '',
          deviceName: '',
          value: ''
        },
        serviceFormVisible: false,
        serviceForm: {
          identifier: '',
          productKey: '',
          deviceName: '',
          params: []
        },
        deviceId: "",
        deviceDetail: {},
        thingModel: {},
        properties: [],
        services: [],
        events: [],
        eventMap: {},
        formInline: {
          page: 1,
          limit: 10,
        },
        // 分页参数
        pageparm: {
          currentPage: 1,
          pageSize: 10,
          total: 10
        },
        showConsole: false,
        mqttClient: null,
        deviceLogs: []
      }
    },
    // 注册组件
    components: {
      Pagination
    },
    /**
     * 数据发生改变
     */

    /**
     * 创建完毕
     */
    created() {
      this.getdata()
    },

    /**
     * 里面的方法只有被调用才会执行
     */
    methods: {
      getdata() {
        this.deviceId = this.$route.query.deviceId
        this.loading = true
        DeviceDetail(this.deviceId)
          .then(res => {
            this.loading = false
            if (res.state && res.state.onlineTime) {
              res.onlineTime = res.state.onlineTime
            } else {
              res.onlineTime = ''
            }
            let prop = res.property || {};
            this.deviceDetail = res

            this.loading = true
            GetThingModel(res.productKey)
              .then(data => {
                this.loading = false
                let model = data.model
                this.thingModel = model
                let props = [];
                model.properties.forEach(p => {
                  props.push({
                    identifier: p.identifier,
                    name: p.name,
                    value: prop[p.identifier],
                    write: p.accessMode != 'r'
                  })
                })
                this.properties = props
                this.services = model.services

              })

          })
      },
      // 分页插件事件
      callFather(parm) {
        this.formInline.page = parm.currentPage
        this.formInline.limit = parm.pageSize
        this.getEvents(this.formInline)
      },
      logSearch() {
        this.formInline.page = 0;
        this.getEvents(this.formInline);
      },
      getEvents(params) {
        DeviceEvents(this.deviceDetail.deviceId, params).then(res => {
          // 分页赋值
          this.pageparm.currentPage = this.formInline.page
          this.pageparm.pageSize = this.formInline.limit
          this.pageparm.total = res.count

          res.data.map(de => {
            if (de.request.params == null) {
              delete de.request.params;
            }

            let name = "未知事件"

            let modeEvents = this.thingModel.events;
            if (modeEvents && modeEvents.length > 0) {
              modeEvents.forEach(e => {
                if (de.identifier == e.identifier) {
                  name = e.name;
                  return;
                }
              })
            }

            let modeServices = this.thingModel.services;
            if (de.identifier == "propertySetReply") {
              name = "属性设置回复";
            } else if (de.identifier == "propertyPost") {
              name = "属性上报";
            }else if (de.identifier == "propertySet") {
              name = "属性设置";
            }else if(modeServices && modeServices.length > 0){
              modeServices.forEach(e => {
                if (de.identifier.replace("_reply", "") == e.identifier) {
                  name = e.name;
                  return;
                }
              })
            }

            if (de.identifier.indexOf("_reply")>0) {
              name=name+"回复";
              de.identifier = de.identifier.replace("_reply", "Reply");
            }
            de.name = name;
            return de;
          })
          res.data.forEach(e=>{
            if(e.request.code==null){
              delete e.request.code;
            }
          })

          this.events = res.data
        })
      },
      handleClick(tab) {
        if (tab.name == "event") {
          this.getEvents(this.formInline);
        } else {
          this.getdata();
        }
      },
      showWriteProperty(prop) {
        this.propertyWriteFormVisible = true
        this.title = '设置属性'
        this.propertyWriteForm.identifier = prop.identifier
        this.propertyWriteForm.productKey = this.deviceDetail.productKey
        this.propertyWriteForm.deviceName = this.deviceDetail.deviceName
        this.propertyWriteForm.value = prop.value
      },
      submitPropertyWriteForm() {
        let form = this.propertyWriteForm;
        let prop = {};
        prop[form.identifier] = form.value;
        PropertySet(this.deviceId, prop)
          .then(() => {
            this.$message({
              type: 'info',
              message: '操作成功'
            })
          })
      },
      showInvokeService(service) {
        this.serviceFormVisible = true
        this.title = '服务调用'
        this.serviceForm.identifier = service.identifier
        this.serviceForm.deviceId = this.deviceDetail.deviceId
        let params = [];
        service.inputData.forEach(p => {
          params.push({
            identifier: p.identifier,
            name: p.name,
            value: ''
          })
        })
        this.serviceForm.params = params
      },
      submitServiceForm() {
        let form = this.serviceForm;
        let param = {}
        this.serviceForm.params.forEach(p => {
          param[p.identifier] = p.value
        })

        ServiceInvoke(this.deviceId, form.identifier, param).then(() => {
          this.$message({
            type: 'info',
            message: '操作成功'
          })
        })
      },
      closeDialog() {
        this.propertyWriteFormVisible = false
        this.serviceFormVisible = false
      },
      openDebug() {
        this.showConsole = true
        let mqttClient = window['mqttClient']
        if (mqttClient) {
          mqttClient.end()
        }
        let uid = localStorage.getItem('loginUid')
        let pwd = localStorage.getItem('logintoken')
        mqttClient = mqtt.connect('ws://填写mqtt websocket地址:8083/mqtt', {
          "clientId": "sy_" + uid,
          "username": uid,
          "password": pwd
        })
        window['mqttClient'] = mqttClient
        mqttClient.on('connect', () => {
          console.log("mqtt connected")
          mqttClient.subscribe('/app/' + this.deviceId + "/#", function(err) {
            if (err) {
              console.log("mqtt subscribe error", err)
            }
          })
        })
        mqttClient.on('message', (topic, message) => {
          this.deviceLogs.push(timestampToTime(new Date().getTime()) + " - topic:" + topic.replace("/app/" +
            this.deviceId, "") + ",msg:" + message.toString())
          console.log('receive message:', topic, message.toString())
        })
      },
      closeDebug() {
        this.showConsole = false
        let mqttClient = window['mqttClient']
        if (mqttClient) {
          mqttClient.end()
        }
      },
      clearConsole() {
        this.deviceLogs = []
      }
    }
  }
</script>

<style scoped>
  .grid-label {
    height: 27px;
    line-height: 27px;
    border: 1px solid #ccc;
    border-left: 0;
    padding: 10px 10px;
    font-size: 12px;
  }

  .grid-label.first {
    border-left: 1px solid #ccc;
  }

  .grid-content {
    height: 27px;
    line-height: 27px;
    border: 1px solid #ccc;
    border-left: 0;
    padding: 10px 10px;
    font-size: 12px;
  }

  .header {
    font-weight: bold;
  }

  .border-single .grid-label {
    border-top: 0;
  }

  .border-single .grid-content {
    border-top: 0;
  }

  .console-bar {
    position: fixed;
    bottom: 0;
    width: 100%;
    padding: 5px 5px;
    background-color: #334157;
  }

  .console {
    width: 100%;
    height: 400px;
    padding: 5px 5px;
    margin-top: 10px;
    background-color: #334157;
  }

  .console .output {
    height: 362px;
    overflow-y: auto;
    margin-top: 5px;
    background-color: #000000;
    color: #FFFFFF;
  }
</style>
